package snooker.scoreboard.activity;

import java.util.LinkedList;
import java.util.List;

import snooker.scoreboard.Ball;
import snooker.scoreboard.BallBitmapHandler;
import snooker.scoreboard.BreakImageAdapter;
import snooker.scoreboard.BreakInfo;
import snooker.scoreboard.FileHandler;
import snooker.scoreboard.FileListAdapter;
import snooker.scoreboard.Frame;
import snooker.scoreboard.Match;
import snooker.scoreboard.RedBall;
import snooker.scoreboard.Settings;
import snooker.scoreboard.SnookerFileException;
import snooker.scoreboard.action.IFreeBallActionListener;
import snooker.scoreboard.action.IInfoActionListener;
import snooker.scoreboard.action.IUndoActionListener;
import snooker.scoreboard.action.IUnintendedRedActionListener;
import snooker.scoreboard.button.AbstractControlButton;
import snooker.scoreboard.button.FoulButton;
import snooker.scoreboard.button.FreeBallButton;
import snooker.scoreboard.button.IButton;
import snooker.scoreboard.button.InfoButton;
import snooker.scoreboard.button.UndoButton;
import snooker.scoreboard.button.UnintendedRedButton;
import snooker.scoreboard.event.StartActivityTouchListener;
import snooker.scoreboard.webservice.WebConnector;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class SnookerScoreboardActivity 
				extends Activity 
				implements OnLongClickListener, OnClickListener, IUndoActionListener, IInfoActionListener, IUnintendedRedActionListener, IFreeBallActionListener {

	private static final String LOG_TAG = "Snooker Activity";
	private static final int QUIT_ID = 13;
	private static final int NEW_MATCH_ID = 1;
	private static final int SAVE_MATCH_ID = 2;
	private static final int NEW_FRAME_ID = 3;
	private static final int SET_NUMBER_OF_REDS_ID = 4;
	private static final int LOAD_MATCH_ID = 5;
	private static final int HISTORY_ID = 6;
	private static final int MATCH_STATISTICS_ID = 7;
	private static final int FRAME_STATISTICS_ID = 8;
	private static final int UPLOAD_MATCH_TO_WEB_ID = 9;
	private static final int LOAD_MATCH_FROM_WEB_ID = 10;
	
	private static final int QUIT_GROUP_ID = 0;
	private static final int MATCH_GROUP_ID = 1;
	private static final int FRAME_GROUP_ID = 2;
	
	private Match match;
	
	private TextView player1Name;
	private TextView player2Name;
	private TextView player1Score;
	private TextView player2Score;
	private TextView scores;
	private TextView breakText;
	private Chronometer chronometer;
	
//	private TextCheckBox luckyCheckBox;

	private ImageView redButton;
	private ImageView yellowButton;
	private ImageView greenButton;
	private ImageView brownButton;
	private ImageView blueButton;
	private ImageView pinkButton;
	private ImageView blackButton;
	private ImageView whiteButton;
	
	private GridView breakGridView;
	private BreakImageAdapter bia;
	
	private RedBall redBallBitmap;
	private BallBitmapHandler bbh;

	private IButton undoButton;
	private IButton unintendedButton;
	private IButton freeButton;
	
	private FoulButton foulCheckBox;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		if (match == null) {
			match = Match.getCurrentMatch();
		}
		initComponents();
		refresh();
	}

	private void initComponents() {
		redBallBitmap = new RedBall(getResources());
		bbh = new BallBitmapHandler(getResources());
		undoButton = new UndoButton(this, (ImageView)  findViewById(R.id.undoButton), 
				getResources(), R.drawable.undo1, R.drawable.undo2, R.drawable.undo3);
		new InfoButton(this, (ImageView)  findViewById(R.id.infoButton), 
				getResources(), R.drawable.info1, R.drawable.info2, R.drawable.info3);
		freeButton = new UnintendedRedButton(this, (ImageView)  findViewById(R.id.freeBallButton), 
				getResources(), R.drawable.free1, R.drawable.free2, R.drawable.free3);
		unintendedButton = new FreeBallButton(this, (ImageView)  findViewById(R.id.unintendedRedButton), 
				getResources(), R.drawable.unintended1, R.drawable.unintended2, R.drawable.unintended3);
		foulCheckBox = new FoulButton((ImageView)  findViewById(R.id.foulButton), 
				getResources(), R.drawable.foul1, R.drawable.foul2, R.drawable.foul3);
		
		foulCheckBox.setOnClickListener(this);
		
		player1Name = (TextView) findViewById(R.id.player1Name);
		player2Name = (TextView) findViewById(R.id.player2Name);
		player1Score = (TextView) findViewById(R.id.player1Score);
		player2Score = (TextView) findViewById(R.id.player2Score);
		scores = (TextView) findViewById(R.id.scores);
		breakText  = (TextView) findViewById(R.id.breakText);
		chronometer = (Chronometer) findViewById(R.id.Chronometer01);
		chronometer.setBase(match.getActFrame().getHistory().getStartTime());
		chronometer.start();
		
		breakGridView = (GridView) findViewById(R.id.breakGridView);
		bia = new BreakImageAdapter(new LinkedList<Ball>(), this);
		breakGridView.setAdapter(bia);
		breakGridView.setOnTouchListener(new StartActivityTouchListener(this));
//		luckyCheckBox = new TextCheckBox(getResources(), 
//				(TextView)findViewById(R.id.luckyText));
		redButton = (ImageView)  findViewById(R.id.redButton);
		redButton.setImageBitmap(redBallBitmap.getBitmap(
				match.getActFrame().getReds()));
		yellowButton = (ImageView)  findViewById(R.id.yellowButton);
		greenButton = (ImageView)  findViewById(R.id.greenButton); 
		brownButton = (ImageView)  findViewById(R.id.brownButton);
		blueButton = (ImageView)  findViewById(R.id.blueButton);
		pinkButton = (ImageView)  findViewById(R.id.pinkButton);
		blackButton = (ImageView)  findViewById(R.id.blackButton);
		whiteButton = (ImageView)  findViewById(R.id.whiteButton);
		
		player1Name.setText(match.getPlayer1Name());
		player2Name.setText(match.getPlayer2Name());
		player1Score.setText(Integer.toString(
				match.getActFrame().getPlayer1Score()));
		player2Score.setText(Integer.toString(
				match.getActFrame().getPlayer2Score()));
		scores.setText(match.getPlayer1FrameWins() + 
				" - " + 
				match.getPlayer2FrameWins());
		player1Name.setBackgroundColor(Color.BLUE);
		player1Name.setOnClickListener(this);
		player2Name.setOnClickListener(this);
		player1Name.setOnLongClickListener(this);
		player2Name.setOnLongClickListener(this);
//		luckyCheckBox.setOnClickListener(this);
		redButton.setOnClickListener(this);
		yellowButton.setOnClickListener(this);
		greenButton.setOnClickListener(this);
		brownButton.setOnClickListener(this);
		blueButton.setOnClickListener(this);
		pinkButton.setOnClickListener(this);
		blackButton.setOnClickListener(this);
		whiteButton.setOnClickListener(this);
		if (match.getActFrame().isOn(Ball.FreeBall)) {
			freeButton.enable();
		} else {
			freeButton.disable();
		}
		if (match.getActFrame().getReds() > 0 && foulCheckBox.isChecked()) {
			unintendedButton.enable();
		} else {
			unintendedButton.disable();
		}
		if (match.getActFrame().getPlayer1Score() == 0 
				&& match.getActFrame().getPlayer2Score() == 0) {
			undoButton.disable();
		} else {
			undoButton.enable();
		}
	}
	
	private void refresh() {
		Log.d(LOG_TAG, "refresh()");
		Frame frame = match.getActFrame();
		if (Match.PLAYER1 == frame.getActPlayer()) {
			player1Name.setBackgroundColor(Color.BLUE);
			player2Name.setBackgroundColor(Color.BLACK);
		} else {
			player1Name.setBackgroundColor(Color.BLACK);
			player2Name.setBackgroundColor(Color.BLUE);
		}
		player1Score.setText(Integer.toString(frame.getPlayer1Score()));
		player2Score.setText(Integer.toString(frame.getPlayer2Score()));
		scores.setText(match.getPlayer1FrameWins() + " - " + 
				match.getPlayer2FrameWins());
		unintendedButton.disable();
		if (frame.isOn(Ball.FreeBall)) {
			freeButton.enable();
		} else {
			freeButton.disable();
		}
		if (match.getActFrame().getPlayer1Score() == 0 
				&& match.getActFrame().getPlayer2Score() == 0) {
			undoButton.disable();
		} else {
			undoButton.enable();
		}
		foulCheckBox.setChecked(false);
//		luckyCheckBox.setChecked(false);
		redButton.setEnabled(frame.getReds() > 0);
		redButton.setImageBitmap(redBallBitmap.getBitmap(
				match.getActFrame().getReds()));
		bbh.setEnabled(yellowButton, frame.isOn(Ball.Yellow), Ball.Yellow);
		bbh.setEnabled(greenButton, frame.isOn(Ball.Green), Ball.Green);
		bbh.setEnabled(brownButton, frame.isOn(Ball.Brown), Ball.Brown);
		bbh.setEnabled(blueButton, frame.isOn(Ball.Blue), Ball.Blue);
		bbh.setEnabled(pinkButton, frame.isOn(Ball.Pink), Ball.Pink);
		bbh.setEnabled(blackButton, frame.isOn(Ball.Black), Ball.Black);
		Log.i(LOG_TAG, "refresh() - freeball=" + frame.isOn(Ball.FreeBall));
		BreakInfo info = frame.getBreakInfo();
		String breakInfo = "";
		if (info.getBreakCount() > 0) {
			breakInfo = "Break " + info.getBreakCount();
		}
		breakText.setText(breakInfo);
		refreshBreakLayout(info.getBalls());
	}
	
	private void animateBall(int id) {
		ImageView spaceshipImage = (ImageView) findViewById(id);
		Animation hyperspaceJumpAnimation = 
			AnimationUtils.loadAnimation(this, R.anim.animate_ball);
		spaceshipImage.startAnimation(hyperspaceJumpAnimation);
	}
	
	public void onClick(View v) {
		boolean refresh = true;
		boolean animateButton = true;
		switch (v.getId()) {
		case R.id.player1Name:
			match.getActFrame().selectPlayer(Match.PLAYER1);
			break;
		case R.id.player2Name:
			match.getActFrame().selectPlayer(Match.PLAYER2);
			break;
		case R.id.foulButton:
			foulCheckBox.setChecked(!foulCheckBox.isChecked());
			if (match.getActFrame().getReds() > 0 && foulCheckBox.isChecked()) {
				unintendedButton.enable();
			} else {
				unintendedButton.disable();
			}
			animateButton = false;
			refresh = false;
			break;
//		case R.id.luckyText:
//			luckyCheckBox.setChecked(!luckyCheckBox.isChecked());
//			refresh = false;
//			break;
		case R.id.blackButton:
			match.getActFrame().setScore(Ball.Black, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.blueButton:
			match.getActFrame().setScore(Ball.Blue, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.brownButton:
			match.getActFrame().setScore(Ball.Brown, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.redButton:
			match.getActFrame().setScore(Ball.Red, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.yellowButton:
			match.getActFrame().setScore(Ball.Yellow, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.greenButton:
			match.getActFrame().setScore(Ball.Green, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.pinkButton:
			match.getActFrame().setScore(Ball.Pink, 
					foulCheckBox.isChecked(), false);
			break;
		case R.id.whiteButton:
			match.getActFrame().setScore(Ball.White, 
					foulCheckBox.isChecked(), false);
			break;
		}
		if (refresh)
			refresh();
		if (v instanceof ImageView)
			if (animateButton) 
				animateBall(v.getId());
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		SubMenu matchMenu = menu.addSubMenu("Match");
		SubMenu frameMenu = menu.addSubMenu("Frame");
		SubMenu settingsMenu = 
			menu.addSubMenu("Preferences").setIcon(
					android.R.drawable.ic_menu_preferences);
		menu.add(QUIT_GROUP_ID, QUIT_ID, 0,"Quit").setIcon(
				android.R.drawable.ic_menu_close_clear_cancel);
		
		// Match Menu
		matchMenu.add(MATCH_GROUP_ID, NEW_MATCH_ID, 0,"New Match");
		matchMenu.add(MATCH_GROUP_ID, SAVE_MATCH_ID, 0,"Save Match"); 
		matchMenu.add(MATCH_GROUP_ID, LOAD_MATCH_ID, 0,"Load Match");
		//matchMenu.add(MATCH_GROUP_ID, LOAD_MATCH_FROM_WEB_ID, 0,"Load Match From Web");
		matchMenu.add(MATCH_GROUP_ID, UPLOAD_MATCH_TO_WEB_ID, 0,"Upload Match To Web");
		matchMenu.add(MATCH_GROUP_ID, MATCH_STATISTICS_ID, 0,"Statistics");
		
		// Frame Menu
		frameMenu.add(MATCH_GROUP_ID, NEW_FRAME_ID, 0,"New Frame");
		frameMenu.add(MATCH_GROUP_ID, HISTORY_ID, 0,"History");
		frameMenu.add(MATCH_GROUP_ID, FRAME_STATISTICS_ID, 0,"Statistics");
		
		// Settings Menu
		settingsMenu.add(FRAME_GROUP_ID, SET_NUMBER_OF_REDS_ID, 0,
				"Set Number of reds");
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case QUIT_ID:
			showDialog(QUIT_ID);
			break;
		case NEW_FRAME_ID:
			showDialog(NEW_FRAME_ID);
			break;
		case SET_NUMBER_OF_REDS_ID:
			showDialog(SET_NUMBER_OF_REDS_ID);
			break;
		case NEW_MATCH_ID:
			showDialog(NEW_MATCH_ID);
			break;
		case SAVE_MATCH_ID:
			showDialog(SAVE_MATCH_ID);
			break;
		case HISTORY_ID:
			if (match.getFrames().size() == 0) {
				startFrameHistoryActivity(-1);
			} else {
				Dialog frameHistoryDialog = getFrameListDialog(HISTORY_ID);
				frameHistoryDialog.show();
			}
			break;
		case LOAD_MATCH_ID:
			Dialog dialog = getLoadMatchDialog();
			dialog.show();
			break;
		case MATCH_STATISTICS_ID:
			startActivity(new Intent(this,MatchStatisticsActivity.class));
			break;
		case FRAME_STATISTICS_ID:
			if (match.getFrames().size() == 0) {
				startFrameStatisticsActivity(-1);
			} else {
				Dialog frameDialog = getFrameListDialog(FRAME_STATISTICS_ID);
				frameDialog.show();
			}
			break;
		case UPLOAD_MATCH_TO_WEB_ID:
			final ProgressDialog progressDialog = new ProgressDialog(this);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			progressDialog.setMessage("Uploading...");
			progressDialog.setCancelable(false);
			progressDialog.show();
			new Thread(new Runnable() {
	             public void run() {
	            	 try {
	            		 WebConnector.getInstance().uploadMatch(progressDialog, match);
	            		 progressDialog.setProgress(100);
		                 progressDialog.hide();
					} catch (Exception e) {
					}
	             }
	         }).start();
			
			break;
		case LOAD_MATCH_FROM_WEB_ID:
			match = WebConnector.getInstance().loadMatch();
			break;
		}
		
		return true;
	}
	
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case QUIT_ID:
			return getQuitAlertDialog();
		case SET_NUMBER_OF_REDS_ID:
			return getSetNumberOfRedsAlertDialog();
		case NEW_MATCH_ID:
			return getNewMatchDialog();
		case SAVE_MATCH_ID:
			return getSaveMatchAlertDialog();
		case NEW_FRAME_ID:
			return getNewFrameAlertDialog();
		case LOAD_MATCH_ID:
			return getLoadMatchDialog();
		}
		return null;
	}
	
	public boolean onLongClick(final View v) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);  
		   
		alert.setTitle("Change Name");  
		alert.setMessage("New Name: ");  
		   
		// Set an EditText view to get user input   
		final EditText input = new EditText(this);  
		alert.setView(input); 
		   
		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {  
			public void onClick(DialogInterface dialog, int whichButton) {  
				String name = input.getText().toString();
			 	switch (v.getId()) {
				case R.id.player1Name:
					match.setPlayer1Name(name);
					player1Name.setText(name);
					break;
				case R.id.player2Name:
					match.setPlayer2Name(name);
					player2Name.setText(name);
					break;
				}
		 	}
		});  
		   
		alert.setNegativeButton("Cancel", 
				new DialogInterface.OnClickListener() {  
		   public void onClick(DialogInterface dialog, int whichButton) {  
			 // Canceled.  
		   }  
		});  
		   
		alert.show();
		return true;
	}

	private void newMatch() {
		Match.getCurrentMatch().newMatch();
	}
	
	private void saveMatch() {
		try {
			match.debug();
			FileHandler.saveMatch();
		} catch (SnookerFileException e) {
			e.printStackTrace();
		}
	}
	
	private AlertDialog getQuitAlertDialog() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("Are you sure you want to quit?")
			   .setCancelable(false)
			   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
						SnookerScoreboardActivity.this.finish();
				   }
			   })
			   .setNegativeButton("No", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
				   }
			   });
		AlertDialog alert1 = builder.create();
		return alert1;
	}
	
	private AlertDialog getSetNumberOfRedsAlertDialog() {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);  
		alert.setTitle("Change Number of Reds");  
		alert.setMessage("New value: ");  
		   
		// Set an EditText view to get user input   
		final EditText input = new EditText(this);  
		alert.setView(input);  
		   
		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {  
			public void onClick(DialogInterface dialog, int whichButton) {  
				try {
					int maxReds = Integer.parseInt(input.getEditableText().toString());
					if (maxReds > 0 && maxReds <= 15) {
						//settings.setMaxReds(maxReds);
						Settings.getInstance().setMaxReds(maxReds);
						showDialog(NEW_FRAME_ID);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
		 	}
		});  
		   
		alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {  
		   public void onClick(DialogInterface dialog, int whichButton) {  
			 // Canceled.  
		   }  
		});  
		   
		AlertDialog alert2 = alert.create();
		return alert2;
	}
	
	private AlertDialog getNewMatchDialog() {
		AlertDialog.Builder builder3 = new AlertDialog.Builder(this);
		builder3.setMessage("Do you want to save current match?")
			   .setCancelable(true)
			   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   match.newFrame(true, Settings.getInstance().getMaxReds());
					   saveMatch();
					   newMatch();
					   resetChronometer();
					   refresh();
				   }
			   })
			   .setNegativeButton("No", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   newMatch();
					   resetChronometer();
					   refresh();
				   }
			   });
		AlertDialog alert4 = builder3.create();
		return alert4;
	}
	
	private AlertDialog getSaveMatchAlertDialog() {
		AlertDialog.Builder builder4 = new AlertDialog.Builder(this);
		builder4.setMessage("Do you want to save current frame?")
			   .setCancelable(true)
			   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   match.newFrame(true, Settings.getInstance().getMaxReds());
					   saveMatch();
					   resetChronometer();
					   refresh();
				   }
			   })
			   .setNegativeButton("No", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   saveMatch();
					   refresh();
				   }
			   });
		AlertDialog alert5 = builder4.create();
		return alert5;
	}
	
	private AlertDialog getNewFrameAlertDialog() {
		AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
		builder2.setMessage("Do you want to save current frame?")
			   .setCancelable(true)
			   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   match.newFrame(true, Settings.getInstance().getMaxReds());
					   resetChronometer();
					   refresh();
				   }
			   })
			   .setNegativeButton("No", new DialogInterface.OnClickListener() {
				   public void onClick(DialogInterface dialog, int id) {
					   match.newFrame(false, Settings.getInstance().getMaxReds());
					   resetChronometer();
					   refresh();
				   }
			   });
		AlertDialog alert3 = builder2.create();
		return alert3;
	}
	
	private Dialog getLoadMatchDialog() {
		String[] fileList = new String[0];
		try {
			fileList = FileHandler.getFileNames();
		} catch (SnookerFileException e1) {
			e1.printStackTrace();
		}
		final FileListAdapter fla = new FileListAdapter(fileList);
		return new AlertDialog.Builder(SnookerScoreboardActivity.this)
		.setTitle("Load Match")
		.setAdapter(fla, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				String fileName = fla.getItem(which).toString();
				Log.i(LOG_TAG, fileName);
				//Toast.makeText(getApplicationContext(), fileName,
				//Toast.LENGTH_SHORT).show();
				try {
					FileHandler.loadMatch(fileName);
					Log.i(LOG_TAG, "****************** Load Match **********************");
					match.debug();
					initComponents();
					resetChronometer();
					refresh();
				} catch (SnookerFileException e) {
					e.printStackTrace();
				}
				dialog.cancel();
				}
		})
		.create();
	}
	
	private Dialog getFrameListDialog(final int who) {
		Log.i(LOG_TAG, who + "");
		final Dialog dialog = new Dialog(this);
		dialog.setContentView(R.layout.file_list_layout); 
		int size = match.getFrames().size();
		String[] list = new String[size+1];
		list[0] = "Actual Frame";
		Log.i(LOG_TAG, "Frame=" + list[0]);
		for (int i = 1; i <= size; i++) {
			list[i] = "Frame " + i;
			Log.i(LOG_TAG, "Frame=" + list[i]);
		}
		ListView lv = (ListView) dialog.findViewById(R.id.ListView01);
		lv.setAdapter(new ArrayAdapter<String>(this,
				  android.R.layout.simple_list_item_1, list));
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
				int position, long id) {
				Log.i(LOG_TAG, "position=" + position);
				int frameId = position - 1; 
				if (who == FRAME_STATISTICS_ID) {
					Log.i(LOG_TAG, who + "");
					startFrameStatisticsActivity(frameId);
				} else if (who == HISTORY_ID) {
					Log.i(LOG_TAG, who + "");
					startFrameHistoryActivity(frameId);
				}
				dialog.cancel();
			}
		});
		return dialog;
	}
	
	private void refreshBreakLayout(List<Ball> balls) {
		if (balls != null) {
			Log.i(LOG_TAG, "Balls size: " + balls.size());
			bia.setBalls(balls);
			breakGridView.setAdapter(bia);
		}
	}
	
	private void startFrameHistoryActivity(int frameId) {
		Intent i = new Intent(this,FrameHistoryActivity.class);
		i.putExtra("frameid", frameId);
		startActivity(i);
	}

	private void startFrameStatisticsActivity(int frameId) {
		Intent i = new Intent(this,FrameStatisticsActivity.class);
		i.putExtra("frameid", frameId);
		startActivity(i);
	}
	
	private void resetChronometer() {
		chronometer.setBase(SystemClock.elapsedRealtime());
	}

	public void undo() {
		match.getActFrame().undo();
		refresh();
	}

	public void showInfo() {
		Toast.makeText(this, 
				match.getActFrame().getInfo(),
				Toast.LENGTH_SHORT).show();
	}

	public void unintendedRed() {
		Toast.makeText(this, "Free Ball", Toast.LENGTH_SHORT).show();
		match.getActFrame().setScore(Ball.FreeBall, 
				false, false);
		refresh();
	}

	public void freeBall() {
		Toast.makeText(this, "Unintended Red", Toast.LENGTH_SHORT).show();
		match.getActFrame().unintendedRed(false);
		refresh();
	}
	
}
